{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Rmagic Functions Extension\n",
    "rpy2 is a convenient way to execute R-code inside a Python environment. However, this also requires that R has been installed on the current system.\n",
    "\n",
    "Like Python, R is free, and can be obtained from https://cran.r-project.org/\n",
    "\n",
    "Note that this is a very rudimentary demonstration, and only demonstrates that R code and graphics can be used quite simply from within Python.\n",
    "\n",
    "author: Thomas Haslwanter date: April-2020"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "## Line magics"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "IPython has an `rmagic` extension that contains a some magic functions for working with R via rpy2. This extension can be loaded using the `%load_ext` magic as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Programs\\WPy64-3760\\python-3.7.6.amd64\\lib\\site-packages\\rpy2\\robjects\\pandas2ri.py:17: FutureWarning: pandas.core.index is deprecated and will be removed in a future version.  The public classes are available in the top-level namespace.\n",
      "  from pandas.core.index import Index as PandasIndex\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'%.3f'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from rpy2.robjects import r\n",
    "\n",
    "%load_ext rpy2.ipython\n",
    "%precision 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## A simple example: scatter-plot\n",
    "A typical use case one imagines is having some numpy arrays, wanting to compute some statistics of interest on these\n",
    " arrays and return the result back to python. Let's suppose we just want to fit a simple linear model to a scatterplot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x1feb1bdd108>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# First we generate and plot the data in Python\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "X = np.array([0,1,2,3,4])\n",
    "Y = np.array([3,5,4,6,7])\n",
    "plt.scatter(X, Y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Pushing Python variables into R, and executing R-commands in IPython\n",
    "\n",
    "We can accomplish this by first pushing variables to R, fitting a model and returning the results. The line magic %Rpush copies its arguments to variables of the same name in rpy2. The %R line magic evaluates the string in rpy2 and returns the results. In this case, the coefficients of a linear model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3.2, 0.9])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%Rpush X Y\n",
    "%R lm(Y~X)$coef"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([9.5])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Note: %Rpush is equivalent to calling %R with just -i and no trailing code.\n",
    "A = np.arange(20)\n",
    "%R -i A\n",
    "%R mean(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3.2, 0.9)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# We can check that the computation in R is correct fairly easily:\n",
    "\n",
    "Xr = X - X.mean()\n",
    "Yr = Y - Y.mean()\n",
    "slope = (Xr*Yr).sum() / (Xr**2).sum()\n",
    "intercept = Y.mean() - X.mean() * slope\n",
    "(intercept, slope)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-2.5,  0.9])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# It is also possible to return more than one value with %R.\n",
    "%R resid(lm(Y~X)); coef(lm(X~Y))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Capturing literal output from R into IPython"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <span>ListVector with 11 elements.</span>\n",
       "    <table>\n",
       "      <tbody>\n",
       "      \n",
       "      <tr>\n",
       "      <th>\n",
       "        call\n",
       "      </th>\n",
       "      <td>\n",
       "        \n",
       "    <span>Vector with 2 elements.</span>\n",
       "    <table>\n",
       "      <tbody>\n",
       "      <tr>\n",
       "      \n",
       "      <td>\n",
       "        RObject\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        Vector\n",
       "      </td>\n",
       "      \n",
       "      </tr>\n",
       "      </tbody>\n",
       "    </table>\n",
       "    \n",
       "      </td>\n",
       "      </tr>\n",
       "      \n",
       "      <tr>\n",
       "      <th>\n",
       "        terms\n",
       "      </th>\n",
       "      <td>\n",
       "        Y ~ X\n",
       "\r\n",
       "attr(,\"variables\")\n",
       "\r\n",
       "list(Y, X)\n",
       "\r\n",
       "attr(,\"factors\")\n",
       "\r\n",
       "  X\n",
       "\r\n",
       "Y 0\n",
       "\r\n",
       "X 1\n",
       "\r\n",
       "attr(,\"term.labels\")\n",
       "\r\n",
       "[1] \"X\"\n",
       "\r\n",
       "attr(,\"order\")\n",
       "\r\n",
       "[1] 1\n",
       "\r\n",
       "attr(,\"intercept\")\n",
       "\r\n",
       "[1] 1\n",
       "\r\n",
       "attr(,\"response\")\n",
       "\r\n",
       "[1] 1\n",
       "\r\n",
       "attr(,\".Environment\")\n",
       "\r\n",
       "<environment: R_GlobalEnv>\n",
       "\r\n",
       "attr(,\"predvars\")\n",
       "\r\n",
       "list(Y, X)\n",
       "\r\n",
       "attr(,\"dataClasses\")\n",
       "\r\n",
       "        Y         X \n",
       "\r\n",
       "\"numeric\" \"numeric\" \n",
       "\n",
       "      </td>\n",
       "      </tr>\n",
       "      \n",
       "      <tr>\n",
       "      <th>\n",
       "        residuals\n",
       "      </th>\n",
       "      <td>\n",
       "        \n",
       "    <span>Array with 5 elements.</span>\n",
       "    <table>\n",
       "      <tbody>\n",
       "      <tr>\n",
       "      \n",
       "      <td>\n",
       "        -0.200000\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        0.900000\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        -1.000000\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        0.100000\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        0.200000\n",
       "      </td>\n",
       "      \n",
       "      </tr>\n",
       "      </tbody>\n",
       "    </table>\n",
       "    \n",
       "      </td>\n",
       "      </tr>\n",
       "      \n",
       "      <tr>\n",
       "      <th>\n",
       "        ...\n",
       "      </th>\n",
       "      <td>\n",
       "        ...\n",
       "      </td>\n",
       "      </tr>\n",
       "      \n",
       "      <tr>\n",
       "      <th>\n",
       "        adj.r.squared\n",
       "      </th>\n",
       "      <td>\n",
       "        \n",
       "    <span>FloatVector with 1 elements.</span>\n",
       "    <table>\n",
       "      <tbody>\n",
       "      <tr>\n",
       "      \n",
       "      <td>\n",
       "        0.746667\n",
       "      </td>\n",
       "      \n",
       "      </tr>\n",
       "      </tbody>\n",
       "    </table>\n",
       "    \n",
       "      </td>\n",
       "      </tr>\n",
       "      \n",
       "      <tr>\n",
       "      <th>\n",
       "        fstatistic\n",
       "      </th>\n",
       "      <td>\n",
       "        \n",
       "    <span>FloatVector with 3 elements.</span>\n",
       "    <table>\n",
       "      <tbody>\n",
       "      <tr>\n",
       "      \n",
       "      <td>\n",
       "        12.789474\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        1.000000\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        3.000000\n",
       "      </td>\n",
       "      \n",
       "      </tr>\n",
       "      </tbody>\n",
       "    </table>\n",
       "    \n",
       "      </td>\n",
       "      </tr>\n",
       "      \n",
       "      <tr>\n",
       "      <th>\n",
       "        cov.unscaled\n",
       "      </th>\n",
       "      <td>\n",
       "        \n",
       "    <span>Matrix with 4 elements.</span>\n",
       "    <table>\n",
       "      <tbody>\n",
       "      <tr>\n",
       "      \n",
       "      <td>\n",
       "        0.600000\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        -0.200000\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        -0.200000\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        0.100000\n",
       "      </td>\n",
       "      \n",
       "      </tr>\n",
       "      </tbody>\n",
       "    </table>\n",
       "    \n",
       "      </td>\n",
       "      </tr>\n",
       "      \n",
       "      </tbody>\n",
       "    </table>\n",
       "    "
      ],
      "text/plain": [
       "R object with classes: ('summary.lm',) mapped to:\n",
       "<ListVector - Python:0x000001FEB1C95E48 / R:0x000001FEB076DA00>\n",
       "[Vector, Formula, Array, Matrix, ..., FloatVector, FloatVector, FloatVector, Matrix]\n",
       "  call: <class 'rpy2.robjects.vectors.Vector'>\n",
       "  R object with classes: ('lm',) mapped to:\n",
       "<Vector - Python:0x000001FEB1C954C8 / R:0x000001FEB1F8A018>\n",
       "[RObject, Vector]\n",
       "  terms: <class 'rpy2.robjects.Formula'>\n",
       "  R object with classes: ('terms', 'formula') mapped to:\n",
       "<Formula - Python:0x000001FEB1C95948 / R:0x000001FEB1FA3D50>\n",
       "  residuals: <class 'rpy2.robjects.vectors.Array'>\n",
       "  R object with classes: ('array',) mapped to:\n",
       "<Array - Python:0x000001FEB1C95448 / R:0x000001FEB1F74220>\n",
       "[-0.200000, 0.900000, -1.000000, 0.100000, 0.200000]\n",
       "  coefficients: <class 'rpy2.robjects.vectors.Matrix'>\n",
       "  R object with classes: ('matrix',) mapped to:\n",
       "<Matrix - Python:0x000001FEB1C95C08 / R:0x000001FEB2007918>\n",
       "[3.200000, 0.900000, 0.616441, 0.251661, 5.191085, 3.576237, 0.013884, 0.037386]\n",
       "...\n",
       "  sigma: <class 'rpy2.robjects.vectors.FloatVector'>\n",
       "  R object with classes: ('numeric',) mapped to:\n",
       "<FloatVector - Python:0x000001FEB1C90708 / R:0x000001FEB1FF9EE0>\n",
       "[0.810000]\n",
       "  df: <class 'rpy2.robjects.vectors.FloatVector'>\n",
       "  R object with classes: ('numeric',) mapped to:\n",
       "<FloatVector - Python:0x000001FEB1C905C8 / R:0x000001FEB1FF9EA8>\n",
       "[0.746667]\n",
       "  r.squared: <class 'rpy2.robjects.vectors.FloatVector'>\n",
       "  R object with classes: ('numeric',) mapped to:\n",
       "<FloatVector - Python:0x000001FEB1C90648 / R:0x000001FEB2012D88>\n",
       "[12.789474, 1.000000, 3.000000]\n",
       "  adj.r.squared: <class 'rpy2.robjects.vectors.Matrix'>\n",
       "  R object with classes: ('matrix',) mapped to:\n",
       "<Matrix - Python:0x000001FEB1C90308 / R:0x000001FEB2012CE8>\n",
       "[0.600000, -0.200000, -0.200000, 0.100000]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Unfortunately, the literal output from R does not work directly (yet):\n",
    "%R summary(lm(Y~X))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "Therefore we have to use a trick:\n",
    "* We first \"capture\" the output of the R-command\n",
    "* And then we display it, line-by-line\n",
    "\n",
    "Note: \"%%R\" executes multiple R-commandlines "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "%%R\n",
    "X = c(1,2,3,4,5)\n",
    "Y = c(1,2,3,6,5)\n",
    "s = capture.output(summary(lm(Y~X)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# to get the variable back in to Python, we use \n",
    "# r from rpy2.robjects\n",
    "spy = r['s']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lm(formula = Y ~ X)\n",
      "\n",
      "Residuals:\n",
      "        1         2         3         4         5 \n",
      "-2.22e-16 -2.00e-01 -4.00e-01  1.40e+00 -8.00e-01 \n",
      "\n",
      "Coefficients:\n",
      "            Estimate Std. Error t value Pr(>|t|)  \n",
      "(Intercept)  -0.2000     1.0132  -0.197   0.8561  \n",
      "X             1.2000     0.3055   3.928   0.0294 *\n",
      "---\n",
      "Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n",
      "\n",
      "Residual standard error: 0.9661 on 3 degrees of freedom\n",
      "Multiple R-squared:  0.8372,\tAdjusted R-squared:  0.7829 \n",
      "F-statistic: 15.43 on 1 and 3 DF,  p-value: 0.02937\n"
     ]
    }
   ],
   "source": [
    "for line in spy[2:-1]:\n",
    "    print(line)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Getting R-variables back into IPython\n",
    "\n",
    "There are two  line magics, %Rpull and %Rget. Both are useful after some R code has been executed and there are variables\n",
    "in the rpy2 namespace that one would like to retrieve. The main difference is that one returns the value (%Rget), while the other pulls it to self.shell.user_ns (%Rpull).\n",
    "\n",
    "Imagine we've stored the results of some calculation in the variable \"a\" in rpy2's namespace. By using the %R magic, we can obtain these results and store them in b. We can also pull them directly to user_ns with %Rpull. They are both views on the same data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "b = %R a=resid(lm(Y~X))\n",
    "#two equivalent ways of getting things into Python\n",
    "%R -o a\n",
    "%Rpull a\n",
    "\n",
    "# and to use it in Python\n",
    "c = r['a']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a = <rpy2.rinterface.FloatSexpVector - Python:0x000001FEB1C76B30 / R:0x000001FEB20C8380>\n",
      "b = [-2.22e-16 -2.00e-01 -4.00e-01  1.40e+00 -8.00e-01]\n",
      "c =             1             2             3             4             5 \n",
      "\n",
      "-2.220446e-16 -2.000000e-01 -4.000000e-01  1.400000e+00 -8.000000e-01 \n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(f'a = {a}')\n",
    "print(f'b = {b}')\n",
    "print(f'c = {c}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "            1             2             3             4             5 \n",
      "\n",
      "-2.220446e-16 -2.000000e-01 -4.000000e-01  1.400000e+00 -8.000000e-01 \n",
      "\n",
      "<rpy2.rinterface.FloatSexpVector - Python:0x000001FEB1C76A50 / R:0x000001FEAF774028>\n",
      "(Intercept)           X \n",
      "\n",
      "       -0.2         1.2 \n",
      "\n"
     ]
    }
   ],
   "source": [
    "%R d=resid(lm(Y~X)); e=coef(lm(Y~X))\n",
    "%R -o d -o e\n",
    "%Rpull e\n",
    "print(d)\n",
    "print(e)\n",
    "\n",
    "print(r['e'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <span>Array with 20 elements.</span>\n",
       "    <table>\n",
       "      <tbody>\n",
       "      <tr>\n",
       "      \n",
       "      <td>\n",
       "               0\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "               1\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "               2\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "               3\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "        ...\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "              16\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "              17\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "              18\n",
       "      </td>\n",
       "      \n",
       "      <td>\n",
       "              19\n",
       "      </td>\n",
       "      \n",
       "      </tr>\n",
       "      </tbody>\n",
       "    </table>\n",
       "    "
      ],
      "text/plain": [
       "R object with classes: ('array',) mapped to:\n",
       "<Array - Python:0x000001FEB1C95B08 / R:0x000001FEB082EB00>\n",
       "[       0,        1,        2,        3, ...,       16,       17,       18,       19]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# The magic %Rget retrieves one variable from R.\n",
    "%Rget A"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Plotting and capturing output\n",
    "\n",
    "R's console (i.e. its stdout() connection) is captured by ipython, as are any plots which are published as PNG files like the notebook with arguments --pylab inline. As a call to %R may produce a return value (see above) we must ask what happens to a magic like the one below. The R code specifies that something is published to the notebook. If anything is published to the notebook, that call to %R returns None."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n"
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "v1 is: [10.2]\n",
      "v2 is: [10.2]\n"
     ]
    }
   ],
   "source": [
    "v1 = %R plot(X,Y); print(summary(lm(Y~X))); vv=mean(X)*mean(Y)\n",
    "print('v1 is:', v1)\n",
    "v2 = %R mean(X)*mean(Y)\n",
    "print('v2 is:', v2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## What value is returned from %R?\n",
    "\n",
    "Some calls have no particularly interesting return value, the magic %R will not return anything in this case. The return value in rpy2 is actually NULL so %R returns None."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Also, if the return value of a call to %R (in line mode) has just been printed to the console, then its value is also not returned."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "v = %R plot(X)\n",
    "assert (v is None)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "But, if the last value did not print anything to console, the value is returned:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "v: [1. 2. 3. 4. 5.]\n"
     ]
    }
   ],
   "source": [
    "v = %R print(summary(X)); X\n",
    "print('v:', v)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "The return value can be suppressed by a trailing ';' or an -n argument.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "%R -n X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "%R X; "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Cell level magic\n",
    "\n",
    "Often, we will want to do more than a simple linear regression model. There may be several lines of R code that we want to \n",
    "use before returning to python. This is the cell-level magic.\n",
    "\n",
    "\n",
    "For the cell level magic, inputs can be passed via the -i or --inputs argument in the line. These variables are copied \n",
    "from the shell namespace to R's namespace using rpy2.robjects.r.assign. It would be nice not to have to copy these into R: rnumpy ( http://bitbucket.org/njs/rnumpy/wiki/API ) has done some work to limit or at least make transparent the number of copies of an array. This seems like a natural thing to try to build on. Arrays can be output from R via the -o or --outputs argument in the line. All other arguments are sent to R's png function, which is the graphics device used to create the plots.\n",
    "\n",
    "We can redo the above calculations in one ipython cell. We might also want to add some output such as a summary\n",
    " from R or perhaps the standard plotting diagnostics of the lm."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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DQGJUxQOcZSUoKgIVTevX7x48d57701ISCgpKTl37lxOTo57OppYdO+O2bMxezZ2766+iTwtDb16CR2ZL7950CLbYdPLU0/h9ddpGlktmjfH2LG0G5ZoReEQx+bNGD3a/dPSpUsff/zxd95554MPPhgxYsQqMZ/P3XorDAZs2YJbb8WcORg5EiYTLl8WOqxqfhcJRbbD5rVr18xm86pVqy698QakUgwfDodBIcqxcRF5+mlx7ob1559/Ll++3Gq11ns9rFCI9LJKFA5xeC8A/ccffwwYMMD5eNCgQYcOHRIorDrzmZ83aRL78/NCJepZHCUlJWPHjj148GDc0aOO+fNt990Hh9WQi8TaX9qwtWuH22/H5s1Cx+Fl+/btqampAL7//vvJkydzn6NFelkl2oY4Kipw8CD693cfGDp06MqVKwFUVlauXLny7rvvFi64enLOz9uyBS+/jN27MWwYdDrs3StgRNzsqMKSDRs2jBs3bvYzz0z58svWOTlZBgOkSp2uAS02GLpnnxXbblgLFy5ct25d6vjxr7z8ct++fb///nteqrXbPG8qyedr8+Lgom2I47vvMHSo54Hp06dXVFQMHTp02LBhcrl8zJgxQoUWuhtvdM3PmzIFb7+N4cOFmp/Hz44qITp37lyXLl1w7hxmzWp/xx3n3n1XuFgiTbdu6NkT+flI4midqnorLS5u88EH2LgRGzd27dr177//5qVapdFillQt9M7DEue1irYbVdav91mtTCKRzJ8/X6hw2OScn3fXXbh6FRs3Ii0NMTF46CFMnMjVin3+IfBTTWjGjBmzbNmyk5WVpaNGvfjiiyn12uiMzJkjoh0af/vt/SNHtm3ZUr5p0+9//bV+/XoFb9t0ieyySrQNcfz4I4YMEToIjjVtiilTkJvrmp939928zc8LNIsjrKW/6qeiouKct9LSUqbq6lbv3r3nz5//xBNPTJgwoX///mlpaa4gxfA5E78+fRAfj19+ETiMa9fw+uv497+75+buGjVqbHJyRkbGu+++265dO4ED48Dp06fXePvjjz+uu+46hmHKysrOnDnDMExRUZHNZvM8EsEPfv65bMiQM0VFYomH6wdxccysWWXffntm+nTmf/8rGzv2zLJlTFmZ53OaNm3KYoviZkeVOrPZbD5nQz///HNiYvVVwKSkpPU0Yyxkzk60gPOc8vKQ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\n"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%R -i X,Y -o XYcoef\n",
    "XYlm = lm(Y~X)\n",
    "XYcoef = coef(XYlm)\n",
    "print(summary(XYlm))\n",
    "par(mfrow=c(2,2))\n",
    "plot(XYlm)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Passing data back and forth\n",
    "\n",
    "Currently, data is passed through RMagics.pyconverter when going from python to R and RMagics.Rconverter when \n",
    "going from R to python.\n",
    "\n",
    "The syntax seems to be still under development. But with the examples here, I hope you will find your way through."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "seq1 = np.arange(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "%%R -i seq1 -o seq2\n",
    "seq2 = rep(seq1, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " [1] 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9\n",
      "\n",
      "<class 'rpy2.robjects.vectors.IntVector'>\n"
     ]
    }
   ],
   "source": [
    "print(r['seq2'])\n",
    "print(type(seq2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 0 3 0 5 0 7 0 9 0 1 0 3 0 5 0 7 0 9]\n"
     ]
    }
   ],
   "source": [
    "# To use the rpy2 object with numpy, you have to convert it to an array:\n",
    "py_seq2 = np.array(r['seq2'])\n",
    "py_seq2[::2] = 0\n",
    "print(py_seq2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Output from R seems to be not working for %%R at the moment:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "%%R\n",
    "print(seq2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Once the array data has been passed to R, modifring its contents does not modify R's copy of the data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "seq1[0] = 200\n",
    "%R print(seq1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "But, if we pass data as both input and output, then the value of \"data\" in user_ns will be overwritten and the\n",
    "new array will be a view of the data in R's copy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[200   1   2   3   4   5   6   7   8   9]\n",
      " [1] 200   1   2   3   4   5   6   7   8   9\n",
      "\n",
      "[200   1   2   3   4   5   6   7   8   9]\n"
     ]
    }
   ],
   "source": [
    "print(seq1)\n",
    "%R -i seq1 -o seq1\n",
    "print(seq1)\n",
    "seq1[0] = 200\n",
    "%R print(seq1)\n",
    "seq1_view = %R seq1\n",
    "print(seq1_view)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Exception handling\n",
    "\n",
    "Exceptions are handled by passing back rpy2's exception and the line that triggered it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Error in withVisible({ : object 'nosuchvar' not found\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    %R -n nosuchvar\n",
    "except Exception as e:\n",
    "    print(e.message)\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## R Graphics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%R plot(X,Y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
